iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0
自我挑戰組

程式小萌新的學習筆記系列 第 17

拾柒。利用 application/json 上傳檔案

  • 分享至 

  • xImage
  •  

最近公司專案開始利用 application/json 作為前後端溝通的檔案格式,意味著沒辦法像以前一樣在表單內用 multipart/form-data 格式上傳檔案了。前幾天算是找到一個解法,趁著記憶猶新分享一下。

json 的天生限制

雖然 json 是目前最流行的檔案交換格式,大部分的 API 都是以這個格式傳送資料,但它最大的問題就是沒辦法放二進位檔案內容。為了解決這個問題,我們需要把二進位檔案內容轉換成可以用文字表達的形式,這時候就輪到 DataURL 出馬了。

DataURL [^1]

dataURL 是一種把檔案內容轉換成一行「類網址」的呈現方式,最大好處是可以將檔案內嵌在網頁中,而不用再發送封包請求跟主機要檔案。以下是一個 dataURL 的範例:
data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==

  • data: 代表它是 DataURL
  • text/plain; 這是 MIME 類型的宣告,代表它的檔案格式
  • base64, 編碼方式
  • SGVsbG8sIFdvcmxkIQ== 經過編碼的二進位檔案內容

FileReader.readAsDataURL() [^2]

知道了上面的 DataURL 之後,我們需要瀏覽器提供的方便功能把 file 轉換成 DataURL。

...
<input type="file" name="myfile">
...
const file = document.querySelector("input[name=myfile]")
const reader = new FileReader()
const dataURL = FileReader.readAsDataURL(file)
console.log(dataURL)

透過以上方是我們可以很順利地把檔案轉換成可以透過 json 傳送的字串,再來就是打包成 json 透過 axios 送出,然後在後端利用 base64_decode 的方式把那段 dataURL 再轉成 file 了。

擺脫了 multipart/form-data 之後,相信透過 application/json 傳送資料又更加方便了

注意事項

需要小小注意的地方是經過 base64 編碼之後的內容都會膨脹約 33% 的容量,如果要上傳容量較大的檔案需要注意後端主機是否接受?另外瀏覽器也有限制 dataURL 的長度上限,詳情可參考 Data_URLs - MDN 內的長度限制段落

以上,今天分享到這裡,謝謝大家縮看,我們明天見~

[^1]: Data_URLs - MDN
[^2]: FileReader.readAsDataURL() - Web APIs | MDN


上一篇
拾陸。書籤小工具 - 一鍵複製網址和標題
下一篇
拾捌。淺談幾種 POST request 的格式
系列文
程式小萌新的學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言